<template>

    <div class="app-container">
        <el-container style="margin-left: 16px; margin-bottom: 15px" >
            <el-autocomplete
                v-model="listQuery.user"
                :fetch-suggestions="querySearch"
                clearable
                class="d3"
                style="width: 200px;"
                placeholder="查询用户 Search User"
                @select="handleSelect"
                :prefix-icon="iconSearch"
                @keyup.enter="handleFilter" />

            <!-- <el-input
                 v-model="listQuery.user"
                 class="d3"
                 placeholder="用户 User"
                 :prefix-icon="iconSearch"
                 @keyup.enter="handleFilter"/> -->

            <el-input
                v-model="listQuery.fileName"
                class="d3"
                placeholder="文件名 file name"
                :prefix-icon="iconSearch"
                @keyup.enter="handleFilter"/>

            <!-- <el-input
                 v-model="listQuery.eventType"
                 class="d3"
                 placeholder="操作种类 Event Type"
                 :prefix-icon="iconSearch"
                 @keyup.enter="handleFilter"/> -->

            <el-select
                v-model="listQuery.eventType"
                placeholder="记录种类 Event Type"
                class="d3"
                @change="handleFilter"
            >

                <el-option v-for="item in eventTypes" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>


            <div class="d3">
                <!-- <span class="demonstration">With shortcuts</span> -->
                <el-date-picker
                    v-model="dateRange"
                    type="datetimerange"
                    :shortcuts="datetimeShortcuts"
                    range-separator="-"
                    start-placeholder="开始时间"
                    end-placeholder="结束时间"
                />
            </div>
        </el-container>


        <el-table :key="tableKey" v-loading="listLoading" :data="list"
                                  class="main-table"
                                  fit
                                  highlight-current-row
                                  style="width: 100%;"
                                  height="100%"
                                  @sort-change="sortChange"
        >
            <el-table-column label="ID" prop="id" width="100"> </el-table-column>
            <el-table-column label="用户 User" prop="user" width="100"> </el-table-column>
            <el-table-column label="操作 Operation" width="400">
                <template v-slot="{row}"> {{row.desc()}} </template>
            </el-table-column>

            <el-table-column label="检测时间 Observation Time" sortable="custom">
                <template v-slot="{row}"> {{parseTime(row.time, '{y}-{m}-{d} 星期{a} {h}:{i}:{s}')}} </template>
            </el-table-column>

            <el-table-column label="已存证 Chained" prop="chained" width="200">
                <template v-slot="{row}"> 
                    <span v-if="row.chained"> <el-tag type="success">Yes</el-tag> </span>
                    <span v-else> <el-tag type="danger">No</el-tag> </span>
                </template>
            </el-table-column>
            <el-table-column label="存证交易哈希 Tx-Hash" prop="tx_hash">
                <template v-slot="{row}"> <TT>{{row.tx_hash}}</TT> </template>
            </el-table-column>
        </el-table>


    <LottieAnimation :animation-data="ChillPeopleJSON" class="anim1" :auto-play="true" :loop="true" :speed="1" ref="anim" />
    <LottieAnimation :animation-data="R1JSON" class="anim r1" :auto-play="true" :loop="true" :speed="0.05" ref="anim" />
    <LottieAnimation :animation-data="R2JSON" class="anim r2" :auto-play="true" :loop="true" :speed="0.02" ref="anim" />
    <LottieAnimation :animation-data="R3JSON" class="anim r3" :auto-play="true" :loop="true" :speed="0.05" ref="anim" />
    <pagination v-show="totalCount>0" :total="totalCount" v-model:page="listQuery.page" v-model:limit="listQuery.limit" @pagination="getList" />
    </div>
</template>

<script setup lang="ts">
 import { watch, ref, onMounted, defineComponent, markRaw } from 'vue';
 import { Search, Edit, Download, Calendar } from '@element-plus/icons-vue';
 import vWaves from '@/directive/waves'; // 水波纹指令
 import { parseTime } from '@/utils';
 import Pagination from '@/components/Pagination'; // secondary package based on el-pagination
 import { fetchUsers, fetchFs} from '@/api/hi_api';

 import { LottieAnimation } from "lottie-web-vue";
 import WatermelonJSON from "@/assets/watermelon.json";
 import ChillPeopleJSON from "@/assets/administration.json";
 // import ChillPeopleJSON from "@/assets/peopleChillChecking.json";
 import DrinkingJSON from "@/assets/drinking.json";

 import R1JSON from "@/assets/ShapesLoader.json";
 import R2JSON from "@/assets/ShapesLoader1.json";
 import R3JSON from "@/assets/CircularLoader.json";
 import {Tween, Easing} from '@tweenjs/tween.js';
 import {datetimeShortcuts} from '@/dt';
 // interface Cmd {id: number; user: string; cmd: string;
 //     argv: string; time: string; chained: boolean; tx_hash: string;
 // }

 const eventTypes = [
     {value: 'CREATE', label: '创建 Create'},
     {value: 'REMOVE', label: '删除 Delete'},
     {value: 'RENAME', label: '重命名 Rename'},
     {value: 'WRITE', label: '更改/写入 Write'},
     {value: '', label: '全部 All'},
 ]

 const dateRange = ref<[Date, Date]>([
     new Date(0),// yesterday
     new Date(),// now
 ]);

 watch(dateRange, async (x) => {
     console.log('🦜: dateRange changed to:', x);
     listQuery.value.sinceTime = parseTime(x[0], '{y}-{m}-{d} {h}:{i}:{s}');
     listQuery.value.untilTime = parseTime(x[1], '{y}-{m}-{d} {h}:{i}:{s}');
     await handleFilter();
 });


 class FileIORecord {
     id: number;
     user: string | undefined
     time: string;
     fileName: string;
     fileTo: string;
     eventType: string;
     chained: boolean;
     tx_hash: string;
     constructor(
         id: number, user: string, time: number, fileName: string, fileTo: string, eventType: string, tx_hash: string
     ) {
         this.id = id;
         this.user = user;
         this.fileName = fileName;
         this.fileTo = fileTo;
         this.eventType = eventType;
         this.time = new Date(time).toString();
         this.chained = tx_hash ? (tx_hash.length > 0) : false;
         this.tx_hash = tx_hash;
     }

     desc(): string {
         if (this.eventType === 'DELETE' || this.eventType === 'TRASH' || this.eventType === 'REMOVE'){
             return `删除了 ${this.fileName}`;
         }else if(this.eventType === 'CREATE'){
             return `创建了 ${this.fileName}`;
         }else if(this.eventType === 'RENAME'){
             return `重命名了 ${this.fileName} 为 ${this.fileTo}`;
         }else if(this.eventType === 'WRITE'){
             return `写入（更改）了 ${this.fileName}`;
         }else{
             return `${this.eventType}: ${this.fileName}`;
         }
     }
 };

 let anim = ref();

 interface ListQuery {
     page: number; limit: number; user: string | undefined;
     eventType: string | undefined;
     fileName: string | undefined; hash: string | undefined;
     sinceTime: string | undefined; untilTime: string | undefined;
     sort: string;
     ascending: boolean;
     // user: string | undefined;
 }

 interface RestaurantItem {value: string; link: string;}// a placeholder for the dropdown list
 interface User {name: string; uidInt: number;}

 const iconSearch = markRaw(Search);
 const tableKey = ref(0);
 const list = ref<FileIORecord[]>([]);
 const listQuery = ref<ListQuery>(
     { page: 1, limit: 20, user: '', eventType: '', fileName: '', hash: '', sort: '', ascending: false,
       sinceTime: '', untilTime: '' }
 );

 const getList = async () => {
     // 🦜: fetch the list from the remote
     /*
        🦜: what we need
        let l = [
        {"id": 1, "time": 1733207632469, "eventType": "CREATE", "fileName": "/home/me/Desktop/hi.txt", "fileTo": "", "user": "me", "tx_hash": "0x1234"},
        {"id": 2, "time": 1733207632469, "eventType": "DELETE", "fileName": "/home/me/Desktop/hi.txt", "fileTo": "", "user": "me", "tx_hash": ""},
        {"id": 3, "time": 1733207632469, "eventType": "CREATE", "fileName": "/home/me/Desktop/hi.txt", "fileTo": "", "user": "me", "tx_hash": "0x1234"},
        {"id": 4, "time": 1733207632469, "eventType": "RENAME", "fileName": "/home/me/Desktop/hi.txt", "fileTo": "/home/me/Desktop/hi.txt", "user": "me"}
        ];

        l = l.map((c: any) => {
        return new FileIORecord(c.id, c.user, c.time, c.fileName, c.fileTo, c.eventType, c.tx_hash);
        });
        list.value = l;

        totalPage.value = 1;
        totalCount.value = 1;

      */

     // --------------------------------------------------
     // 1. fetch
     let lq = listQuery.value;
     let o = await fetchFs(lq);
     // 1.1 🦜 : the code check is in utils/request.js
     console.log('🦜 : fetched fss:', o);

     // 2. make it clean for our usage, in particular:
     /*
        2.1. convert its time (in unix epoch) to Date
        2.2 if it has a hash, then it is chained
      */
     o = o['data']
     let vl = o['voList']
     vl = vl.map((c: any) => {
        return new FileIORecord(c.id, c.user, c.time, c.fileName, c.fileTo, c.eventType, c.tx_hash);
        });

     // 3. set the list
     list.value = vl;
     // 4. set the total Pages
     totalPage.value = o['totalPages'];
     totalCount.value = o['totalCount'];

 }

 const handleFilter = async () => {
     console.log(`🦜 : handleFilter() with `, listQuery.value);
     await getList();
 };

 const totalPage = ref(1);
 const totalCount = ref(1);
 const users = ref<User[] | null>(null);

 const listLoading = ref(false);
 const user2uid = ref<Map<string, number> | null>(null);
 const uid2user = ref<Map<number, string> | null>(null);

 onMounted(async () => {
     listLoading.value = true;
     let response = await fetchUsers();
     users.value = response.data;
     listLoading.value = false;

     users.value as User[]
     if (users.value !== null){
         user2uid.value = new Map(users.value.map((u: User) => [u.name, u.uidInt]));
         uid2user.value = new Map(users.value.map((u: User) => [u.uidInt, u.name]));

         console.log(`🦜 : table created and got ${users.value.length} users, user2uid:`, user2uid.value);
         // console.log(`🦜 : uid2user:`, this.uid2user);
         await getList();
     }else{
         ElMessage({message: "🦜: Error getting users", type: 'error'});
     }

     // our animation
     setTimeout(() => {
         console.log(anim.value.goToAndPlay(150, true));
         anim.value;
    }, 500);


     // r1's rotation
     // --------------------------------------------------
     const ar1 = document.querySelector('.anim.r1');
     const ar2 = document.querySelector('.anim.r2');
     const ar3 = document.querySelector('.anim.r3');
     // const ar4 = document.querySelector('.anim.r4');
     // console.log('🦜: ar1', ar1);
     // rotate the .anim.r1's rotation
     const tween = new Tween({rotation: 0})
         .to({rotation: 360}, 200000)
         .onUpdate((obj) => {
             let r = obj.rotation;
             ar1.style.transform = `rotate(${r}deg)`;
             ar2.style.transform = `rotate(${r}deg)`;
             ar3.style.transform = `rotate(${r}deg)`;
             // ar4.style.transform = `rotate(${r}deg)`;
         })
         .repeat(Infinity)
         .start();
     
     
     function update(time) {
         requestAnimationFrame(update);
         tween.update(time);
     }
     requestAnimationFrame(update);

 });

 const handleSelect = (item: RestaurantItem) => {
     console.log(`🦜 selected user = `, item); // 🦜 : nothing to be done here....
 };

 const querySearch = (queryString: string, cb: any) => {
     const l = users.value;
     let r = queryString ? l.filter(
         (u: User) => u.name.toLowerCase().includes(queryString.toLowerCase())
     ) : l;
     r = r.map((u: User) => ({ value: u.name }));
     // an array of {value}
     // call callback function to return suggestions
     cb(r);
 };

 const sortChange = async (data: any) => {
     const { prop, order } = data;
     console.log('🦜 : sortChange ->', prop, order);
     listQuery.value.ascending = order === 'ascending';
     if (order) {
         listQuery.value.sort = "";
     } else {
         listQuery.value.sort = prop;
         console.assert(prop === 'time', '❌️ : prop should be time');
     }
     await getList();
 };

 const getSortClass = (key: string) => {
     const sort = listQuery.value.sort;
     return sort === `+${key}` ? 'ascending' : 'descending';
 };
</script>


<style lang="scss">
 @use 'base'
</style>
